#include "simulator.h"

Simulator::Simulator(char *scenario_desc, int heuristic_id, int error, double gridUnavailability) {
	/*Init the Simgrid environment*/
	SG_init();
	/*Set epsilon*/
	long double epsilon = 0.00000000001;
	SG_setEpsilon(epsilon);
	fprintf(stderr, "\nUsing epsilon=%Lg\n", epsilon);	
	/*Instantiate the scenario from its description file*/
	scenariogenerator = ScenarioGenerator::getInstance();
	scenario = scenariogenerator->makeScenarioFromDescription(scenario_desc, gridUnavailability);
	
	/*Instantiate the scheduler*/
	scheduler = new Scheduler(scenario, heuristic_id, error);

}

Simulator::~Simulator() {
	delete scheduler;
	delete scenariogenerator;
	delete scenario;
	SG_clear();
}

Scheduler *Simulator::getScheduler() {
	return this->scheduler;
}

Scenario *Simulator::getScenario() {
	return this->scenario;
}

void Simulator::resetConfigurations() {
	this->scheduler->resetJob();
	this->scheduler->updateGridResourcesOffset(SG_getClock());
	SG_reset(); // reset simgrid tasks and resources		
}

void Simulator::simulate() {
	
	for (int exec = 0; exec<scenario->getNumberOfExecutions(); exec++) {
		/*Reset the simulation environment (tasks)*/
		this->resetConfigurations();

		/*Schedule and execute the Job onto the Grid. Returns the application makespan*/
		long double makespan = scheduler->schedule();
		
		/*Print the makespan of this execution*/
		fprintf(stdout,"\n---------------\nMakespan for execution #%d = %Lf\n-------------\n", (exec+1), makespan);
	}
	
}

void Simulator::makeScenarioFromModel(const char *xmlModelFile, const char *result) {
	/*Init the Simgrid environment*/
	SG_init();
	
	/*Instances a scenario from a model.xml file*/
	Scenario *scenario = ScenarioGenerator::getInstance()->makeScenarioFromModel(xmlModelFile);
	/*Write the scenario to a XML file*/
	scenario->writeToXML(result);	

	/*Release memory used*/	
	delete scenario;	
	SG_clear();
	
}

void Simulator::convertScenario(const char *sourceScenario_description, const char *resultScenario_description, const char *conversionResult) {
	/*Init the Simgrid environment*/	
	SG_init();

	Scenario *result = ScenarioGenerator::getInstance()->convertScenario(sourceScenario_description, resultScenario_description);
	
	result->writeToXML(conversionResult);
	
	delete result;	
	SG_clear();
}
